package com.mtconnect.dao;

import com.mtconnect.exception.DAOException;
import com.mtconnect.exception.JDBCException;
import com.mtconnect.model.Condition;
import com.mtconnect.util.JDBCTemplete;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/8/4.
 */
public class ConditionMapper implements Mapper<Condition> {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConditionMapper.class);
    private JDBCTemplete jdbcTemplete;

    public ConditionMapper(JDBCTemplete jdbcTemplete) {
        this.jdbcTemplete = jdbcTemplete;
    }

    public Integer insertCondition(String tableName, Condition condition) throws DAOException {

        LOGGER.debug("param is {} \n {}", tableName, condition);
        String sql = "INSERT INTO '" + tableName + "' ('name','sequence','timestamp','dataItemID','subType','warningType') VALUES(?,?,?,?,?,?)";
        PreparedStatement statement = null;
        try {
            statement = jdbcTemplete.getConnection().prepareStatement(sql);
            statement.setString(1, condition.getName());
            statement.setLong(2, condition.getSequence());
            statement.setTimestamp(3, condition.getTimestamp());
            statement.setString(4, condition.getDataItemID());
            statement.setString(5, condition.getSubType());
            statement.setString(6, condition.getWarningType());
            return statement.executeUpdate();
        } catch (SQLException e) {
            LOGGER.error("insert condition table error", e);
            throw new DAOException(e);
        } finally {
            LOGGER.debug("execute sql is ===> {}", sql);
            try {
                jdbcTemplete.close(null, statement, null);
            } catch (JDBCException e) {
                LOGGER.warn("insert condition table statement close error", e);
                throw new DAOException(e);
            }
        }
    }

    @Override
    public List<Condition> nonSubTypeBySample(String tableName, String id, Long from, Long count) throws DAOException {
        LOGGER.debug("param is  tableName={},id={},from={},count={}", tableName, id, from, count);
        String sql = "SELECT * FROM \"" + tableName + "\" WHERE dataItemID=? AND \"sequence\" BETWEEN ? AND ? ORDER BY \"sequence\"";
        LOGGER.debug("execute sql is {}", sql);
        try (PreparedStatement statement = jdbcTemplete.getConnection().prepareStatement(sql)) {
            statement.setString(1, id);
            statement.setLong(2, from);
            statement.setLong(3, from + count);
            ResultSet resultSet = statement.executeQuery();
            List<Condition> conditions = new ArrayList<>();
            while (resultSet.next()) {
                conditions.add(allocateCondition(resultSet));
            }
            resultSet.close();
            return conditions;
        } catch (SQLException e) {
            throw new DAOException(e);
        }
    }

    @Override
    public List<Condition> subTypeBySample(String tableName, String id, String subType, Long from, Long count) throws DAOException {
        LOGGER.debug("param is  tableName={},id={},from={},count={},subTypeBySample={}", tableName, id, from, count,subType);
        String sql = "SELECT * FROM " + tableName + " WHERE dataItemID = ? AND subType = ? AND \"sequence\" BETWEEN ? AND ? ORDER BY \"sequence\"";
        LOGGER.debug("execute sql is {}", sql);
        try (PreparedStatement statement = jdbcTemplete.getConnection().prepareStatement(sql)) {
            statement.setString(1, id);
            statement.setString(2, subType);
            statement.setLong(3, from);
            statement.setLong(4, from + count);
            ResultSet resultSet = statement.executeQuery();
            List<Condition> conditions = new ArrayList<>();
            while (resultSet.next()) {
                conditions.add(allocateCondition(resultSet));
            }
            resultSet.close();
            return conditions;
        } catch (SQLException e) {
            throw new DAOException(e);
        }
    }

    @Override
    public Condition nonSubTypeByCurrent(String tableName, String id, String at) throws DAOException {
        LOGGER.debug("param is  tableName={},id={},at={}", tableName, id, at);
        String sql = "SELECT * FROM " + tableName + " WHERE dataItemId=? AND \"sequence\"<=? ORDER BY \"sequence\" DESC";
        LOGGER.debug("execute sql is {}", sql);
        try (PreparedStatement statement = jdbcTemplete.getConnection().prepareStatement(sql)){
            statement.setString(1,id);
            statement.setLong(2,Long.parseLong(at));
            ResultSet resultSet = statement.executeQuery();
            Condition condition = null;
            if (resultSet.next()) {
                condition = allocateCondition(resultSet);
            }
            return condition;
        } catch (SQLException e) {
            throw new DAOException(e);
        }
    }

    @Override
    public Condition subTypeByCurrent(String tableName, String id, String subType, String at) throws DAOException {
        LOGGER.debug("param is  tableName={},id={},at={},subType={}", tableName, id, at,subType);
        String sql = "SELECT * FROM " + tableName + " WHERE dataItemId=? AND subType=? AND \"sequence\"<=? ORDER BY \"sequence\" DESC";
        LOGGER.debug("execute sql is {}", sql);
        try (PreparedStatement statement = jdbcTemplete.getConnection().prepareStatement(sql)){
            statement.setString(1,id);
            statement.setString(2,subType);
            statement.setLong(3,Long.parseLong(at));
            ResultSet resultSet = statement.executeQuery();
            Condition condition = null;
            if (resultSet.next()) {
                condition = allocateCondition(resultSet);
            }
            resultSet.close();
            return condition;
        } catch (SQLException e) {
            throw new DAOException(e);
        }
    }

    private Condition allocateCondition( ResultSet resultSet) throws SQLException {
            Condition condition = new Condition();
            condition.setName(resultSet.getString("name"));
            condition.setSequence(resultSet.getLong("sequence"));
            condition.setTimestamp(resultSet.getTimestamp("timestamp"));
            condition.setDataItemID(resultSet.getString("dataItemID"));
            condition.setSubType(resultSet.getString("subType"));
            condition.setQualifier(resultSet.getString("qualifier"));
            condition.setNativeCode(resultSet.getString("nativeCode"));
            condition.setNativeSeverity(resultSet.getString("nativeSeverity"));
            condition.setStatistic(resultSet.getString("statistic"));
            condition.setWarningType(resultSet.getString("warningType"));
            condition.setValue("value");
            return condition;
    }
}
